﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace TTIServer
{
	/// <summary>
	/// Interaction logic for RotationMenu.xaml
	/// </summary>
	public partial class RotationMenu : Window
	{
		public delegate void AngleRenderCallback(float angle, float distance);
		public delegate void RotationMenuDisplay();

		float ang1 = 0, ang2 = -1, ang3 = -1, ang4 = -1;
		float high = -1, low = -1;

		public bool HILO = false;

		private List<String> _stopLabels;
		private List<Point> _stopPoints;
		private int _numberOfStops;
		private Point midPoint;
		private double ThetaVal;
		private int _radius;

		public RotationMenu(int numberOfStops, List<String> StopLabels)
		{
			this.InitializeComponent();

			_stopLabels = StopLabels;
			_numberOfStops = numberOfStops;
			_stopPoints = new List<Point>(_numberOfStops);
			ThetaVal = 2 * Math.PI / _numberOfStops;
			midPoint.X = this.MainCircle.Width / 2;
			midPoint.Y = this.MainCircle.Height / 2;
			_radius = (int)(MainCircle.Height / 2);  //Either width or height.
			RotateTransform myRT = new RotateTransform(90, midPoint.X, midPoint.Y);
			MainCircle.RenderTransform = myRT;
			// Insert code required on object creation below this point.
		}

		private void drawStops()
		{
			/* s = (PI*r*Angle)/180 */

			for (int i=0; i<_numberOfStops;i++)
			{
				Point tempPoint = PointOnCircle(midPoint,i*ThetaVal,_radius);
				Line stopLine = new Line();
				
				stopLine.Stroke = new SolidColorBrush(Color.FromRgb(0, 0, 0));
				stopLine.StrokeThickness = 1.0;
				stopLine.Visibility = Visibility.Visible;
				stopLine.X1 = midPoint.X;
				stopLine.Y1 = midPoint.Y;
				stopLine.X2 = tempPoint.X;
				stopLine.Y2 = tempPoint.Y;
				stopLine.SnapsToDevicePixels = true;
				_stopPoints.Add(tempPoint);

				//Time to add the stop label
				TextBlock stopLabel = new TextBlock();
				stopLabel.Text = _stopLabels[i];
				
				stopLabel.FontFamily = new FontFamily("Verdana");
				stopLabel.FontSize = 16.0;
				stopLabel.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
				stopLabel.VerticalAlignment = System.Windows.VerticalAlignment.Center;
				stopLabel.TextAlignment = System.Windows.TextAlignment.Center;
				
				
				Point labelPoint = PointOnCircle(midPoint,(i*ThetaVal+(ThetaVal*0.5)),_radius*0.75);
				Point LabelMidPoint = new Point(stopLabel.ActualWidth / 2, stopLabel.ActualHeight / 2);

				#region Line Debug Code
				//For Debug Purposes
				//Line stopLabelLine = new Line();
				//stopLabelLine.Stroke = new SolidColorBrush(Color.FromRgb(255, 0, 0));
				//stopLabelLine.StrokeThickness = 1.0;
				//stopLabelLine.Visibility = Visibility.Visible;
				//stopLabelLine.X1 = midPoint.X;
				//stopLabelLine.Y1 = midPoint.Y;
				//stopLabelLine.X2 = labelPoint.X;
				//stopLabelLine.Y2 = labelPoint.Y;
				//stopLabelLine.SnapsToDevicePixels = true;
				//MainCircle.Children.Add(stopLabelLine);
				//stopLabel.BorderBrush = new SolidColorBrush(Color.FromRgb(255, 0, 0));
				//stopLabel.BorderThickness = new Thickness(1);
				#endregion

				//Force a layout so that the program can get the Actual Height/Width
				stopLabel.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
				stopLabel.Arrange(new Rect(0, 0, stopLabel.DesiredSize.Width, stopLabel.DesiredSize.Height));

				MainCircle.Children.Add(stopLabel);
				MainCircle.Children.Add(stopLine);
				stopLabel.RenderTransformOrigin = new Point(0.5, 0.5);
				double leftPos = labelPoint.X - (stopLabel.ActualWidth / 2);
				double topPos = labelPoint.Y - (stopLabel.ActualHeight / 2);
				stopLabel.Margin = new Thickness(leftPos, topPos, 0, 0);
				double stopLabelDeg = 180 / Math.PI * (i * ThetaVal + (ThetaVal * 0.5));

				RotateTransform myRT = new RotateTransform(90+stopLabelDeg, LabelMidPoint.X, LabelMidPoint.Y);
				stopLabel.RenderTransform = myRT;
			}
			



		}

		//A point at angle theta on the circle whose centre is (x0,y0) 
		//and whose radius is r is (x0 + r cos theta, y0 + r sin theta). 
		//Now choose theta values evenly spaced between 0 and 2pi.
		
		private Point PointOnCircle(Point midPoint, double Radians, double Radius)
		{
			double tX, tY;
			tX = midPoint.X + (Radius * Math.Cos(Radians));
			tY = midPoint.Y + (Radius * Math.Sin(Radians));
			return new Point(tX, tY);
		}

		public void setRotationAngle(float angle, float distance)
		{
			float avgAngle = 0;

			if (ang2 == -1)
			{
				ang2 = angle;
				ang3 = angle;
				ang4 = angle;
			}
			else
			{

				ang4 = ang3;
				ang3 = ang2;
				ang2 = ang1;
				ang1 = angle;



			}

			//avgAngle = (ang1 + ang2 + ang3 + ang4) / 4;
			this.Dispatcher.BeginInvoke(new AngleRenderCallback(rotateMain), new object[] { angle / 10, distance / 10 });

		}

		/// <summary>
		/// This call shows or hides (and selects stop under pointer) the rotation menu
		/// </summary>
		/// <param name="shouldShow">true shows the menu, false hides the menu</param>
		public void ShowRotationMenu( bool shouldShow )
		{

			if (shouldShow)
				this.Dispatcher.BeginInvoke(new RotationMenuDisplay(Show));
			else
				this.Dispatcher.BeginInvoke(new RotationMenuDisplay(Hide));

		}

		public void rotateMain(float ang, float distance)
		{
			if (HILO == true)
				if (high == -1)
				{
					low = ang;
					high = ang;
				}
				else
				{
					low = ang < low ? ang : low;
					high = ang > high ? ang : high;
				}
			else
			{
				high = -1;
				low = -1;
			}



			label1.Content = (distance).ToString();
			label2.Content = (high.ToString());
			label3.Content = low.ToString();

			float newAng = (high + low) / 2;

			RotateTransform myRT = new RotateTransform(90-ang, midPoint.X, midPoint.Y);
			MainCircle.RenderTransform = myRT;


		}

		private void Window_Loaded(object sender, System.Windows.RoutedEventArgs e)
		{
			// TODO: Add event handler implementation here.
			drawStops();

		}


	}
}
